package com.ug_project.spring_dict.Controllers

import com.ug_project.spring_dict.WebApiV1
import com.ug_project.spring_dict.com.ug_project.spring_dict.DataAccess.FavoriteRepository
import com.ug_project.spring_dict.com.ug_project.spring_dict.DataAccess.SearchRepository
import com.ug_project.spring_dict.com.ug_project.spring_dict.Entities.Favorite
import com.ug_project.spring_dict.com.ug_project.spring_dict.Entities.FavoritesInUser
import io.ktor.application.Application
import io.ktor.auth.authenticate
import io.ktor.http.HttpStatusCode
import io.ktor.locations.*
import io.ktor.response.respond
import io.ktor.routing.get
import io.ktor.routing.route
import io.ktor.routing.routing


fun Application.favoriteModule() {

    routing {
        location<WebApiV1> {
            route("Favorites") {
                authenticate {

                    @Location("")
                    data class FavoriteInsertEntity(var name: String, var direction: String, var accessibility: Int = FavoritesInUser.Companion.Accessibility.PRIVATE)
                    put<FavoriteInsertEntity> {
                        val user = context.user()
                        if (user == null) {
                            context.respond(HttpStatusCode.NotFound)
                            return@put
                        }
                        val accessibilities = arrayOf(FavoritesInUser.Companion.Accessibility.PRIVATE, FavoritesInUser.Companion.Accessibility.PROTECTED, FavoritesInUser.Companion.Accessibility.PUBLIC)
                        if (it.accessibility !in accessibilities) {
                            context.respond(HttpStatusCode.BadRequest)
                            return@put
                        }

                        val fav = FavoriteRepository().insertFavorite(user.id, Favorite(user.id, it.direction, it.name), it.accessibility)
                        context.response.status(HttpStatusCode.Created)
                        context.respond(fav)
                    }

                    get {
                        val user = context.user()
                        if (user == null) {
                            context.respond(HttpStatusCode.NotFound)
                            return@get
                        }
                        val favs = FavoriteRepository().getAllFavorites(user.id)
                        context.respond(favs)
                    }

                    @Location("{id}")
                    data class DeleteEntity(var id: Int)
                    delete<DeleteEntity> {
                        val repo = FavoriteRepository()
                        val user = context.user() ?: return@delete
                        val favInUser = repo.getFavoritesInUserByFavoriteId(it.id, user.id) ?: return@delete
                        val fav = repo.getFavoriteById(it.id) ?: return@delete

                        if (user.id == fav.creatorId) {
                            repo.removeWordsByFavoriteId(fav.id)
                            repo.removeFavoritesInUserById(favInUser.id)
                            repo.removeFavoritesById(fav.id)
                        }
                        else {
                            repo.removeFavoritesInUserByFavoriteIdAndUserId(favInUser.id, user.id)
                        }

                        context.respond(HttpStatusCode.OK)
                    }

                    @Location("{id}")
                    data class FavoriteWordEntity(var wordId: Int, var id: Int)
                    put<FavoriteWordEntity> {
                        val repo = FavoriteRepository()
                        val fav = repo.getFavoriteById(it.id) ?: return@put
                        val word = SearchRepository().getWordById(fav.langCode, it.wordId) ?: return@put
                        val user = context.user() ?: return@put
                        if (!repo.checkManagemenityOfWord(user.id, it.id)){
                            context.respond(HttpStatusCode.BadRequest)
                            return@put
                        }
                        val wordInFavs = repo.addToFavorites(fav.langCode, fav.id, word.id)
                        context.respond(wordInFavs)
                    }

                    @Location("{id}/Words")
                    data class GetWordFromFavorite(var id: Int)
                    get<GetWordFromFavorite> {
                        val repo = FavoriteRepository()
                        val user = context.user() ?: return@get
                        val favInUser = repo.getFavoritesInUserByFavoriteId(it.id, user.id) ?: return@get
                        val fav = repo.getFavoriteById(favInUser.favoriteId) ?: return@get
                        context.respond(repo.getWordsInFavoriteByFavoriteId(fav))
                    }

                    @Location("{favoriteId}/Words/{wordId}")
                    data class RemoveWordsInFavoritesModel(var favoriteId: Int, var wordId: Int)
                    delete<RemoveWordsInFavoritesModel> {
                        val user = context.user() ?: return@delete
                        val repo = FavoriteRepository()
                        if (!repo.checkManagemenityOfWord(user.id, it.favoriteId)){
                            context.respond(HttpStatusCode.BadRequest)
                            return@delete
                        }
                        repo.removeWordsInFavorites(it.wordId)
                        context.respond(HttpStatusCode.OK)
                    }
                }
            }
        }
    }
}

